﻿Public Class LvlNet

    Public Lines As New List(Of LvlLine)
    Private mStns As LvlStations
    Private LevelNodes As New List(Of LvlPoint)
    Private LevelBMs As New List(Of LvlPoint)
    Private RemaindStations As New List(Of Integer)

    Private AdjustLines As New List(Of LvlLine), BHCs As New List(Of String)
    Private NotAdjustLines As New List(Of LvlLine)
    Private ErrorPerStation As Double = 9999



    Sub New(ByRef Stns As LvlStations)
        mStns = Stns
        '若最后站为无效站，则删除
        'If Not (mStns.LevelStations(mStns.LevelStations.Count - 1).BackPoint.ValidPoint) Then
        '    mStns.LevelStations.RemoveAt(mStns.LevelStations.Count - 1)
        '    'If mStns.CurrentStationIndex > mStns.LevelStations.Count - 1 Then
        '    '    mStns.CurrentStationIndex = mStns.LevelStations.Count - 1
        '    'End If
        'End If

        LevelBMs = MyShared.ProjectOpt.BMs
        'Dim sBMs() As String = frmRead.ProjectOpt.BMs  'lvlRegistry.OptionDef.BMs.Split(vbCrLf)
        'For Each BM As String In sBMs
        'Dim Itm() As String = BM.Trim.Split(":")
        'If Itm.Length = 2 Then LevelBMs.Add(New LvlPoint(Itm(0), CDbl(Itm(1))))
        'Next


        'Dim vP1 As LvlCompare.ComparePoint, Vp2 As LvlCompare.ComparePoint, vP3 As LvlCompare.ComparePoint
        'vP1.Name = "BM1"
        'vP1.Level = 4.5

        'Vp2.Name = "BM2"
        'Vp2.Level = 4.245
        'vP3.Name = "BM3"
        'vP3.Level = 4.16
        'LevelBMs.Add(vP1)
        'LevelBMs.Add(Vp2)
        'LevelBMs.Add(vP3)
    End Sub

    ''' <summary>
    ''' 返回测站的文本字符串
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Overrides Function ToString() As String
        LvlSvPoint.LineNumber = 0

        Dim sTmp As New System.Text.StringBuilder

        sTmp.Append("            等级水准手簿" & vbCrLf & vbCrLf)
        sTmp.Append("仪器:" & MyShared.CurrentOpt.InstrNo)
        sTmp.Append("  尺号:" & MyShared.CurrentOpt.Staff1 & "+" & MyShared.CurrentOpt.Staff2)
        sTmp.Append("  尺常数:" & MyShared.ProjectOpt.JiFuCha / MyShared.ProjectOpt.MidReadUnit)
        sTmp.Append(vbCrLf & "天气:" & MyShared.CurrentOpt.Weather)
        sTmp.Append("     日期:" & Now.ToString("yy-MM-dd") & vbCrLf & vbCrLf)

        sTmp.Append("基准点" & vbCrLf)
        For Each vP As LvlPoint In LevelBMs
            sTmp.Append(vP.Name & "," & vP.Level.ToString("0.00000").PadLeft(8, " "c) & ";")
        Next
        sTmp.Append(vbCrLf & vbCrLf)

        If LevelNodes.Count > 0 Then
            sTmp.Append("水准节点" & vbCrLf)
            For Each vP As LvlPoint In LevelNodes
                sTmp.Append(vP.Name & "," & vP.Level.ToString("0.00000").PadLeft(8, " "c) & ";")
            Next
            sTmp.Append(vbCrLf)
        End If

        If ErrorPerStation < 9000 Then
            sTmp.Append("测站中误差：" & Format(ErrorPerStation * 1000, "0.00mm") & vbCrLf & vbCrLf)
        End If

        '参与平差的闭合环
        Dim BhcIdx As Integer = 0
        If BHCs.Count > 0 Then
            sTmp.Append("闭合差统计" & vbCrLf)
            For I As Integer = 0 To BHCs.Count - 1
                BhcIdx = I + 1
                Dim sBHC As String = BHCs(I)
                sTmp.Append("Closer" & BhcIdx.ToString & ":" & sBHC)

                Dim vP() As String = sBHC.Split("→")
                Dim Height As Double = 0
                If vP.Length > 1 Then
                    For J As Integer = 0 To vP.Length - 2
                        Height += FoundAdjustLineHeightByStartAndEnd(vP(J), vP(J + 1))
                    Next
                    Height += FoundBMLevelbyName(vP(0))
                    Height -= FoundBMLevelbyName(vP(vP.Length - 1))
                    sTmp.Append("  闭合差：" & Format(Height * 1000, "0.00mm"))
                End If
                sTmp.Append(vbCrLf)
            Next
        End If

        '不参与平差的附合路线或闭合路线
        For Each vLine As LvlLine In NotAdjustLines
            With vLine
                If vLine.LineStationCount = 0 Then
                    '没有前视的测站，不存在闭合差

                ElseIf OrderInList(.StartPoint, LevelBMs) > -1 And OrderInList(.EndPoint, LevelBMs) > -1 Then
                    '两端都是基准点，附合线路
                    BhcIdx += 1
                    sTmp.Append("Closer" & BhcIdx.ToString & ":" & "From " & .StartPoint & " To " & .EndPoint & _
                            "  闭合差:" & Format((.EndLevel - .StartLevel - .LineHeight) * 1000, "0.00mm") & vbCrLf)



                ElseIf vLine.EndPoint = vLine.StartPoint Then
                    '闭合水准线路，不参与平差
                    BhcIdx += 1
                    sTmp.Append("Closer" & BhcIdx.ToString & ":" & "From " & .StartPoint & " To " & .EndPoint & _
                            "  闭合差:" & Format(.LineHeight * 1000, "0.00mm") & vbCrLf)

                ElseIf OrderInList(.EndPoint, LevelBMs) = -1 And OrderInList(.EndPoint, LevelNodes) = -1 Then
                    '终点既不是基准点，也不是节点,支水准，不计算闭合差

                Else
                    '设为参与平差的水准线路
                    AdjustLines.Add(vLine)
                End If
            End With
        Next
        sTmp.Append(vbCrLf & vbCrLf)

        '依次输出第测段的数据
        For I As Integer = 0 To Lines.Count - 1
            Dim vLine = Lines(I)
            sTmp.Append("测段" & (I + 1).ToString & "   " & vbCrLf)
            vLine.LineStatistic()
            sTmp.Append(vLine.ToStringWithoutDateTime)
            sTmp.Append(vbCrLf)
        Next

        '中视支点
        If RemaindStations.Count > 0 Then
            sTmp.Append("中视支点")
            For Each Idx As Integer In RemaindStations
                sTmp.Append(mStns.LevelStations(Idx).MidToStringWithoutDateTime)
            Next
        End If

        sTmp.Append(vbCrLf)
        sTmp.Append("观测:" & MyShared.CurrentOpt.Surveyor)
        sTmp.Append("      记录:" & MyShared.CurrentOpt.Recordor)
        sTmp.Append("      检查:" & MyShared.CurrentOpt.Examor & vbCrLf)

        Return sTmp.ToString
    End Function
    Private Function FoundAdjustLineHeightByStartAndEnd(ByVal Name1 As String, ByVal Name2 As String) As Double
        For Each vLine As LvlLine In AdjustLines
            Dim sStart As String = vLine.StartPoint
            Dim sEnd As String = vLine.EndPoint
            Dim Height As Double = vLine.LineHeight

            If Name1 = sStart Then
                If Name2 = sEnd Then
                    Return Height
                End If
            ElseIf Name1 = sEnd Then
                If Name2 = sStart Then
                    Return -Height
                End If
            End If
        Next
        Return 9999
    End Function
    Private Function FoundBMLevelbyName(ByVal Name As String) As Double
        For Each BM As LvlPoint In LevelBMs
            If BM.Name = Name Then Return BM.Level
        Next
        Return 9999
    End Function

    ''' <summary>
    '''  查找节点
    ''' </summary>
    ''' <remarks></remarks>
    Sub SearchNodes()
        Dim mCloser As New lvlCloser(mStns.LevelStations, LevelBMs)
        Dim treev1 As New TreeView
        Dim Forks As New List(Of String)
        mCloser.SearchCloser(treev1, Forks)

        For Each fk As String In Forks
            Dim vP As New LvlPoint(fk, 9999)
            LevelNodes.Add(vP)
        Next

    End Sub


    ''' <summary>
    '''  查找闭合差
    ''' </summary>
    ''' <remarks></remarks>
    Sub SearchBHC()
        If AdjustLines.Count > 0 Then
            Dim mCloser As New lvlCloser(AdjustLines, LevelBMs)
            Dim treev1 As New TreeView
            Dim Forks As New List(Of String)
            BHCs = mCloser.SearchCloser(treev1, Forks)
        End If
    End Sub

    ' <summary>
    ' 水准节点
    ' 先对往返观测的测站只保留一站
    ' 线路中，不包括只有中视与后视点的测站，
    ' 出现过两次以上后视且有不同前视的点  
    ' 或出现有两次以上前视且有不同后视的点
    ' </summary>
    ' <remarks></remarks> 
    'Function SearchNode() As String
    '    '先备份水准路线（有前视）测站

    '    Dim StnsList As New List(Of LvlStation)
    '    For Each stn As LvlStation In mStns.LevelStations
    '        If stn.ForePoint.ValidPoint Then
    '            StnsList.Add(stn)
    '        End If
    '    Next
    '    '往返观测的测站不保留
    '    Dim Found As Boolean
    '    Do
    '        Found = False
    '        For I As Integer = 0 To StnsList.Count - 1
    '            With StnsList(I)
    '                Dim BkName1 As String = .BackPoint.Name
    '                Dim FrName1 As String = .ForePoint.Name
    '                Dim RemovePos As Integer = -1
    '                For J As Integer = 0 To StnsList.Count - 1
    '                    If I <> J Then
    '                        Dim vStn As LvlStation = StnsList(J)
    '                        Dim BkName2 As String = vStn.BackPoint.Name
    '                        Dim FrName2 As String = vStn.ForePoint.Name
    '                        If BkName1 = BkName2 And FrName1 = FrName2 Then
    '                            Found = True
    '                            RemovePos = J
    '                            Exit For
    '                        ElseIf BkName1 = FrName2 And BkName2 = FrName1 Then
    '                            Found = True
    '                            RemovePos = J
    '                            Exit For
    '                        End If
    '                    End If
    '                Next
    '                If Found Then
    '                    Dim nMax As Integer = Math.Max(RemovePos, I)
    '                    'Dim nMin As Integer = Math.Min(RemovePos, I)
    '                    StnsList.RemoveAt(nMax)
    '                    'StnsList.RemoveAt(nMin)
    '                    Exit For
    '                End If
    '            End With
    '        Next
    '    Loop While Found

    '    Dim lstPnts As New List(Of PointRouteTimes)
    '    For Each vStn As LvlStation In StnsList
    '        If vStn.ForePoint.ValidPoint Then
    '            AddPointList(vStn.BackPoint, lstPnts)
    '            AddPointList(vStn.ForePoint, lstPnts)
    '        End If
    '    Next

    '    For Each prt As PointRouteTimes In lstPnts
    '        If prt.Times > 2 Then
    '            Dim vP As New LvlPoint
    '            vP.Name = prt.Name
    '            LevelNodes.Add(vP)
    '        End If
    '    Next

    '    Dim sTmp As String = String.Empty
    '    For Each vp As LvlPoint In LevelNodes
    '        sTmp &= vp.Name & ","
    '    Next
    '    Return sTmp
    'End Function
    'Private Sub AddPointList(ByVal vP As LvlSvPoint, ByRef lstPnts As List(Of PointRouteTimes))
    '    For I As Integer = 0 To lstPnts.Count - 1
    '        If lstPnts(I).Name = vP.Name Then
    '            lstPnts(I).Times += 1
    '            Exit Sub
    '        End If
    '    Next
    '    Dim prt1 As New PointRouteTimes
    '    prt1.Name = vP.Name
    '    prt1.Times = 1
    '    lstPnts.Add(prt1)
    'End Sub
    'Private Class PointRouteTimes
    '    Public Name As String
    '    Public Times As Integer
    'End Class

    ''' <summary>
    ''' 水准测段搜索
    ''' </summary>
    ''' <remarks></remarks>
    Sub SearchLine()
        '线路开始或结束于基准点、结点
        Dim EndPoints As New List(Of String)
        For Each pnt As LvlPoint In LevelBMs
            EndPoints.Add(pnt.Name)
        Next
        For Each pnt As LvlPoint In LevelNodes
            EndPoints.Add(pnt.Name)
        Next

        '全部测站的索引
        Dim StnIndexs As New List(Of Integer)
        For I As Integer = 0 To mStns.LevelStations.Count - 1
            StnIndexs.Add(I)
        Next

        '搜索节点或基准点开始的测站
        Dim Found As Boolean
        For Each pnt In EndPoints
            Found = True
            Do
                Dim vLine As New LvlLine(mStns)
                Found = vLine.Search(pnt, StnIndexs, EndPoints)
                If Found Then Lines.Add(vLine)
            Loop While Found
        Next

        '搜索除起始于基准点或基点外的其它测段
        Do
            Found = False
            For Each Idx As Integer In StnIndexs
                Dim pnt As String = mStns.LevelStations(Idx).BackPoint.Name
                Dim vLine As New LvlLine(mStns)
                Found = vLine.Search(pnt, StnIndexs, EndPoints)
                If Found Then
                    Lines.Add(vLine)
                    Exit For
                End If
            Next
        Loop While Found
        For Each vLine As LvlLine In Lines
            vLine.LineStatistic()
        Next

        '线路搜索后的剩余测站
        For Each Idx As Integer In StnIndexs
            RemaindStations.Add(Idx)
        Next
        Do
            Found = False
            For Each vLine As LvlLine In Lines
                If vLine.LineStationCount = 0 Then
                    Found = True
                    For Each Idx As Integer In vLine.StationIndexs
                        RemaindStations.Add(Idx)
                    Next
                    Lines.Remove(vLine)
                    Exit For
                End If
            Next
        Loop While Found


    End Sub

    ''' <summary>
    ''' 水准平差
    ''' </summary>
    ''' <remarks></remarks>
    Sub Adjust()
        SearchAdjustLines()
        If AdjustLines.Count > 1 Then
            Dim ContinueAdj As Boolean = True
            Dim Xcnt As Integer = LevelNodes.Count      '未知数个数
            Dim X(Xcnt - 1) As Double                   '未知数
            Dim dX(Xcnt - 1, 0) As Double               '未知数的改正数

            Do
                AdjustOneTime(X, AdjustLines, dX)
                For I As Integer = 0 To X.Length - 1
                    X(I) += dX(I, 0)
                Next
                If XXX(dX) < 0.00001 Then ContinueAdj = False
            Loop While ContinueAdj

            For I As Integer = 0 To LevelNodes.Count - 1
                LevelNodes(I) = New LvlPoint(LevelNodes(I).Name, X(I))
            Next

            '计算测站中误差√[pvv]/r
            Dim pvv As Double = 0
            Dim tCnt As Integer = 0
            For Each vLine As LvlLine In AdjustLines
                Dim sStart As String = vLine.StartPoint
                Dim StartLevel As Double = GetNodeOrBMLevelbyName(sStart)

                Dim sEnd As String = vLine.EndPoint
                Dim EndLevel As Double = GetNodeOrBMLevelbyName(sEnd)

                If StartLevel < 9000 And EndLevel < 9000 And vLine.LineStationCount > 0 Then
                    Dim bhc As Double = EndLevel - StartLevel - vLine.LineHeight
                    pvv = bhc * bhc / vLine.LineStationCount
                    tCnt += 1
                End If
            Next
            tCnt = tCnt - LevelNodes.Count
            ErrorPerStation = Math.Sqrt(pvv / tCnt)

        End If
    End Sub
    Private Sub SearchAdjustLines()
        '参与平差的水准线路
        '包括一端点为固定点另一端点为水准节点，或两端点均为水准节点
        '两端均为固定点的水准线路不参与，可直接计算

        For Each vLine As LvlLine In Lines
            vLine.LineStatistic()
            With vLine
                If OrderInList(.StartPoint, LevelBMs) > -1 And OrderInList(.EndPoint, LevelBMs) > -1 Then
                    '两端都是基准点，不必平差
                    NotAdjustLines.Add(vLine)
                ElseIf OrderInList(.EndPoint, LevelBMs) = -1 And OrderInList(.EndPoint, LevelNodes) = -1 Then
                    '终点既不是基准点，也不是节点,支水准，不参与平差
                    NotAdjustLines.Add(vLine)
                ElseIf vLine.EndPoint = vLine.StartPoint Then
                    '闭合水准线路，不参与平差
                    NotAdjustLines.Add(vLine)
                Else
                    '设为参与平差的水准线路
                    AdjustLines.Add(vLine)
                End If
            End With
        Next
    End Sub
    Private Sub AdjustOneTime(ByVal X() As Double, ByRef AdjustLines As List(Of LvlLine), ByRef dX(,) As Double)
        'V=BX+L  X为节点个数
        Dim Xcnt As Integer = X.Length
        Dim Bcnt As Integer = Lines.Count
        Dim B(0 To Bcnt - 1, 0 To Xcnt - 1) As Double   '系数阵
        Dim P(0 To Bcnt - 1, 0 To Bcnt - 1) As Double   '权阵
        Dim L(0 To Bcnt - 1, 0) As Double                  '误差阵

        '每行组成一个误差方程
        For I As Integer = 0 To AdjustLines.Count - 1
            With AdjustLines(I)
                L(I, 0) = -.LineHeight

                Dim J As Integer = OrderInList(.StartPoint, LevelNodes)
                If J > -1 Then
                    B(I, J) = 1
                    P(I, I) = 1 / .LineStationCount
                    L(I, 0) -= X(J)
                End If

                Dim K As Integer = OrderInList(.EndPoint, LevelNodes)
                If K > -1 Then
                    B(I, K) = -1
                    P(I, I) = 1 / .LineStationCount
                    L(I, 0) += X(K)
                End If

                Dim M As Integer = OrderInList(.StartPoint, LevelBMs)
                If M > -1 Then
                    L(I, 0) -= LevelBMs(M).Level
                End If

                Dim N As Integer = OrderInList(.EndPoint, LevelBMs)
                If N > -1 Then
                    L(I, 0) += LevelBMs(N).Level
                End If

            End With
        Next
        Array_Cal(B, L, dX, P)

    End Sub
    Private Function OrderInList(ByVal Name As String, ByVal Lst As List(Of LvlPoint)) As Integer
        For I As Integer = 0 To Lst.Count - 1
            If Lst.Item(I).Name = Name Then
                Return I
            End If
        Next
        Return -1
    End Function
    Private Function XXX(ByVal dx(,) As Double)
        Dim ddd As Double = 0
        For I As Integer = 0 To dx.Length - 1
            Dim xx As Double = dx(I, 0)
            ddd = xx * xx
        Next
        Return Math.Sqrt(ddd)
    End Function
    '''调用矩阵运算
    Private Sub Array_Cal(ByRef Array_A(,) As Double, ByRef Array_L(,) As Double, ByRef Array_DX(,) As Double, ByRef Array_P(,) As Double)
        Dim D1 As Long, D2 As Long
        D1 = UBound(Array_A, 1) - LBound(Array_A, 1)
        D2 = UBound(Array_A, 2) - LBound(Array_A, 2)

        'Dim AT() As Double, ATP() As Double, ATPA() As Double, ATPA_INV() As Double, ATPL() As Double
        Dim AT(D2, D1) As Double
        Matrix_Trans(Array_A, AT)

        Dim ATP(D2, D1) As Double
        Matrix_Mult(AT, Array_P, ATP)

        Dim ATPA(D2, D2) As Double
        Matrix_Mult(ATP, Array_A, ATPA)

        Dim ATPA_INV(D2, D2) As Double
        Matrix_Inv(ATPA, ATPA_INV)

        Dim ATPL(D2, 0) As Double
        Matrix_Mult(ATP, Array_L, ATPL)

        'Dim MA(,) As Double
        Dim MA(D2, D1)
        Matrix_Mult(ATPA_INV, ATPL, Array_DX)

    End Sub
    Private Sub Matrix_Mult(ByRef A(,) As Double, ByRef B(,) As Double, ByRef C(,) As Double)
        '矩阵相乘 n1*n 的矩阵乘以 n*n2 的矩阵结果得矩阵C(n1,n2)
        Dim n As Long, n1 As Long, n2 As Long
        n1 = UBound(A, 1) - LBound(A, 1)
        n = UBound(A, 2) - LBound(A, 2)
        n2 = UBound(B, 2) - LBound(B, 2)

        Dim T1 As Long, T2 As Long, T3 As Long

        For T1 = 0 To n1
            For T2 = 0 To n2
                C(T1, T2) = 0
                For T3 = 0 To n
                    C(T1, T2) = C(T1, T2) + A(T1, T3) * B(T3, T2)
                Next T3
            Next T2
        Next T1
    End Sub
    Private Sub Matrix_Trans(ByRef A(,) As Double, ByRef C(,) As Double)
        '矩阵转置 n1*n2 的矩阵转置成 n2*n1 的矩阵
        Dim n1 As Long, n2 As Long
        n1 = UBound(A, 1) - LBound(A, 1)
        n2 = UBound(A, 2) - LBound(A, 2)

        Dim I As Long, J As Long
        For I = 0 To n1
            For J = 0 To n2
                C(J, I) = A(I, J)
            Next
        Next
    End Sub
    '矩阵求逆
    Private Sub Matrix_Inv(ByRef V(,) As Double, ByRef ReturnValue(,) As Double)
        Dim I As Long, J As Long, k As Long, row As Long, Pivot As Double

        row = UBound(V, 1) - LBound(V, 1)
        Dim M(0 To row, 0 To row) As Double


        For I = 0 To row
            For J = 0 To row
                M(I, J) = V(I, J)
            Next
        Next

        For I = 0 To row
            ReturnValue(I, I) = 1
        Next

        For I = 0 To row
            Pivot = M(I, I) + 1.0E-60
            If Pivot <> 1 Then
                For k = 0 To row
                    M(I, k) = M(I, k) / Pivot
                    ReturnValue(I, k) = ReturnValue(I, k) / Pivot
                Next
            End If
            For J = 0 To row
                Pivot = M(J, I)
                If I <> J And Pivot <> 0 Then
                    For k = 0 To row
                        M(J, k) = M(J, k) - M(I, k) * Pivot
                        ReturnValue(J, k) = ReturnValue(J, k) - ReturnValue(I, k) * Pivot
                    Next
                End If
            Next
        Next
    End Sub

    ''' <summary>
    ''' 各测段计算
    ''' </summary>
    ''' <remarks></remarks>
    Sub Calculate()
        For Each vLine As LvlLine In Lines
            Dim sStart As String = vLine.StartPoint
            Dim StartLevel As Double = GetNodeOrBMLevelbyName(sStart)
            If StartLevel > 9000 Then SearchLevelByName(sStart, StartLevel)

            Dim sEnd As String = vLine.EndPoint
            Dim EndLevel As Double = GetNodeOrBMLevelbyName(sEnd)
            If EndLevel > 9000 Then SearchLevelByName(sEnd, EndLevel)

            If StartLevel < 9999 Or EndLevel < 9999 Then
                vLine.StartLevel = StartLevel
                vLine.EndLevel = EndLevel
                vLine.Calculate()

            End If
        Next

        '残余测站（如中视点引出来的测站等）计算
        For Each Idx As Integer In RemaindStations
            With mStns.LevelStations(Idx)
                If .BackPoint.Level <> "9999" Then
                    Dim BkLvl As Double
                    If SearchLevelByName(.BackPoint.Name, BkLvl) Then
                        .BackPoint.Level = BkLvl
                        .Calculate(0)
                    End If
                End If
            End With
        Next
    End Sub

    Private Function GetNodeOrBMLevelbyName(ByVal Name As String) As Double
        Dim Level As Double = 9999
        Dim iPos As Integer = OrderInList(Name, LevelBMs)
        If iPos > -1 Then
            Level = LevelBMs(iPos).Level
        Else
            iPos = OrderInList(Name, LevelNodes)
            If iPos > -1 Then Level = LevelNodes(iPos).Level
        End If
        Return Level
    End Function
    Private Function SearchLevelByName(ByVal Name As String, ByRef Level As Double) As Boolean
        For I As Integer = 0 To mStns.LevelStations.Count - 1
            With mStns.LevelStations(I)
                If ExamPointByName(.BackPoint, Name, Level) Then Return True
                If ExamPointByName(.ForePoint, Name, Level) Then Return True
                For J As Integer = 0 To .MidPointCount - 1
                    If ExamPointByName(.MidPoint(J), Name, Level) Then Return True
                Next
            End With
        Next
        Level = 9999
        Return False
    End Function
    Private Function ExamPointByName(ByVal vPnt As LvlSvPoint, ByVal Name As String, ByRef Level As Double) As Boolean
        If vPnt.Name = Name Then
            If vPnt.Level <> "9999" Then
                Level = CDbl(vPnt.Level)
                Return True
            End If
        End If
        Return False
    End Function



End Class
